package com.lxm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lxm.common.contants.ItemConstants;
import com.lxm.common.contants.LxmCommentConstants;
import com.lxm.common.tools.ContentUtils;
import com.lxm.common.tools.ImgUrlUtils;
import com.lxm.common.tools.LogicDeleteUtils;
import com.lxm.common.tools.UserHolder;
import com.lxm.dto.ItemDTO;
import com.lxm.dto.Result;
import com.lxm.entity.Item;
import com.lxm.entity.ItemLogic;
import com.lxm.entity.Login;
import com.lxm.mapper.ItemDao;
import com.lxm.service.ItemService;
import com.lxm.service.LoginService;
import com.lxm.service.LxmCommentService;
import com.lxm.service.logicService.ItemLogicService;
import com.lxm.vo.ItemDetailVO;
import com.lxm.vo.ItemPageVO;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2024-10-02
 */
@Service
public class ItemServiceImpl extends ServiceImpl<ItemDao, Item> implements ItemService {
    @Resource
    private ItemLogicService itemLogicService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private LxmCommentService lxmCommentService;
    @Resource
    private LoginService loginService;

    @Override
    public Result getItemTypeList() {
        Map<String, String> itemTypeMap = stringRedisTemplate.opsForHash()
                .entries(ItemConstants.ITEM_TYPE_KEY)
                .entrySet()
                .stream()
                .collect(Collectors.toMap(
                        entry -> entry.getKey().toString(),
                        entry -> entry.getValue().toString()
                ));
        return Result.ok(itemTypeMap);
    }

    @Override
    public Result getMyItemList(Integer current) {
        // 查询用户发布的商品列表
        Long userId = UserHolder.getUser().getUserId();
        // 查询商品列表
        List<Item> itemList = lambdaQuery()
                .eq(Item::getUserId, userId)
                .select(Item::getItemId, Item::getImg, Item::getTitle,
                        Item::getMoney, Item::getSellNum, Item::getUserId)
                .orderByDesc(Item::getCreateTime)
                .page(new Page<>(current, ItemConstants.ITEM_PAGE_SIZE))
                .getRecords();
        // 返回商品列表
        if (CollUtil.isEmpty(itemList)) {
            return Result.ok(itemList);
        }
        // 将商品列表转化为VO
        List<ItemPageVO> itemPageVOList = itemList
                .stream()
                .map(this::getItemPageVO)
                .collect(Collectors.toList());
        // 返回商品列表
        return Result.ok(itemPageVOList);
    }

    /**
     * 新增商品
     *
     * @param itemInfo
     * @return
     */
    @Override
    public Result addItem(ItemDTO itemInfo) {
        // 填充商品信息 例如userid等
        Item item = BeanUtil.copyProperties(itemInfo, Item.class);
        item.setUserId(UserHolder.getUser().getUserId());
        boolean isSuccess = save(item);
        return isSuccess ? Result.ok() : Result.fail(ItemConstants.ADD_ITEM_FAIL);
    }


    @Override
    public Result modifyItem(ItemDTO itemInfo, Long itemId) {
        Item item = BeanUtil.toBean(itemInfo, Item.class);
        Long userId = UserHolder.getUser().getUserId();
        // 更新商品信息,确认商品的卖方是用户本人才可修改
        boolean updateSuccess = update(item, new LambdaQueryWrapper<Item>()
                .eq(Item::getItemId, itemId)
                .eq(Item::getUserId, userId));
        return updateSuccess ? Result.ok(ItemConstants.MODIFY_ITEM_SUCCESS)
                : Result.fail(ItemConstants.MODIFY_ITEM_FAIL);
    }

    /**
     * 批量删除商品,可以单删，全删，自选删
     *
     * @param itemIds
     * @return Result
     */
    @Override
    public Result removeItems(List<Long> itemIds) {
        Long userId = UserHolder.getUser().getUserId();
        if (CollUtil.isEmpty(itemIds)) {
            return Result.fail(ItemConstants.REMOVE_ITEM_FAIL);
        }
        // 批量将商品转化为逻辑删除对象
        List<ItemLogic> itemLogicList = listByIds(itemIds)
                .stream()
                .map(item -> BeanUtil.toBean(item, ItemLogic.class))
                .toList();
        // 批量使用逻辑删除工具类进行逻辑删除
        itemLogicList.stream()
                .filter(itemLogic -> itemLogic.getUserId().equals(userId))
                .forEach(itemLogic ->
                        LogicDeleteUtils.logicDelete(itemLogic.getItemId(),
                                itemLogic, itemLogicService, this));
        return Result.ok();
    }

    public boolean checkItemNumEnough(Long itemId, Integer itemCount) {
        // 查询商品库存
        //只需要知道商品库存即可
        Item item = lambdaQuery()
                .eq(Item::getItemId, itemId)
                .select(Item::getItemNum)
                .one();
        return item.getItemNum() > itemCount;
    }

    //用于商品首页
    @Override
    public Result listItemByTime(Integer current) {
        // 查询商品列表，直接返回最新货物。
        List<Item> itemList = lambdaQuery()
                .orderByDesc(Item::getCreateTime)
                .select(Item::getItemId, Item::getImg, Item::getTitle,
                        Item::getMoney, Item::getSellNum, Item::getUserId)
                .page(new Page<>(current, ItemConstants.ITEM_PAGE_SIZE))
                .getRecords();
        if (CollUtil.isEmpty(itemList)) {
            return Result.ok(itemList);
        }
        List<ItemPageVO> itemPageVOList = itemList
                .stream()
                .map(this::getItemPageVO)
                .collect(Collectors.toList());
        return Result.ok(itemPageVOList);
    }


    @Override
    public Result getItemDetail(Long itemId) {
        Item item = lambdaQuery()
                .eq(Item::getItemId, itemId)
                .one();
        if (BeanUtil.isEmpty(item)) {
            return Result.fail(ItemConstants.ITEM_NOT_EXIST);
        }
        Login userInfoLogin = loginService.getUserInfoLogin(item.getUserId());
        ItemDetailVO itemDetailVO = BeanUtil.toBean(item, ItemDetailVO.class);
        // 设置卖家信息
        itemDetailVO.setNickName(userInfoLogin.getNickName());
        itemDetailVO.setUserImg(userInfoLogin.getIcon());
        // 设置商品图片，返回商品介绍图片数组返回
        itemDetailVO.setImg(ImgUrlUtils.parseImageUrlToList(item.getImg()));
        itemDetailVO.setCommentList(lxmCommentService
                .getDetailCommentList(itemId, LxmCommentConstants.ITEM_TYPE, 1));
        return Result.ok(itemDetailVO);
    }

    @Override
    public Result getItemListByType(Long typeId, Integer current) {
        List<Item> itemList = lambdaQuery()
                .eq(Item::getItemType, typeId)
                .orderByDesc(Item::getCreateTime)
                .select(Item::getItemId, Item::getImg, Item::getTitle,
                        Item::getMoney, Item::getSellNum, Item::getUserId)
                .page(new Page<>(current, ItemConstants.ITEM_PAGE_SIZE))
                .getRecords();
        if (CollUtil.isEmpty(itemList)) {
            return Result.ok(itemList);
        }
        List<ItemPageVO> itemPageVOList = itemList
                .stream()
                .map(this::getItemPageVO)
                .collect(Collectors.toList());
        return Result.ok(itemPageVOList);
    }

    @NotNull
    private ItemPageVO getItemPageVO(Item item) {
        ItemPageVO itemPageVO = BeanUtil.toBean(item, ItemPageVO.class);
        Login userInfoLogin = loginService.getUserInfoLogin(item.getUserId());
        itemPageVO.setTitle(ContentUtils
                .getBriefEnd(itemPageVO.getTitle(), ItemConstants.ITEM_TITLE_BRIEF));
        itemPageVO.setImg(ImgUrlUtils.parseImageCoverUrl(itemPageVO.getImg()));
        // 设置卖家信息
        itemPageVO.setNickName(userInfoLogin.getNickName());
        itemPageVO.setUserImg(userInfoLogin.getIcon());
        return itemPageVO;
    }

}
